package com.haojiang.mh.ui.fragment

import android.util.Log
import android.widget.TextView
import com.haojiang.mh.AppContext
import com.haojiang.mh.R
import com.haojiang.mh.cache.Const
import com.haojiang.mh.cache.MGlobal
import com.haojiang.mh.service.api.JsonCallback
import com.haojiang.mh.service.ble.BleHandle
import com.haojiang.mh.service.entity.*
import com.haojiang.mh.service.event.CardEvent
import com.haojiang.mh.service.event.ReportEvent
import com.haojiang.mh.ui.activity.SleepAdviceActivity
import com.haojiang.mh.ui.base.BaseActivity
import com.haojiang.mh.ui.base.BaseScrollAbleFragment
import com.haojiang.mh.utils.KLog
import com.haojiang.mh.utils.MUtil
import com.haojiang.mh.utils.SpUtil
import com.haojiang.mh.widget.SleepStandardView
import com.haojiang.mh.widget.TopTabLayout
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.Response
import kotlinx.android.synthetic.main.fragment_day.*
import kotlinx.android.synthetic.main.fragment_day.ttl_top_tab
import kotlinx.android.synthetic.main.fragment_two.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

/**
 * 日报
 */
class DayFragment : BaseScrollAbleFragment() {

    private var currDay = ""
    private var currHasReportData = true
    private lateinit var unitHour: String
    private lateinit var unitMin: String
    private var isLeft = true
    private var bean: DayReportBean?=null

    override fun getLayoutId() = R.layout.fragment_day

    override fun initView() {
        unitHour = context.getString(R.string.f_unit_hour)
        unitMin = context.getString(R.string.f_unit_min)
        tv_radar.setOnClickListener { redirectExplain("day_radar") }

        initSleepInfo()

        //初始化最高最低文本显示
        initHeartRateInfo(null)
        initBreathRateInfo(null)

        ttl_top_tab.setOnTabSelectListener { selectTabIndex, _, flag ->
//            if (flag != TopTabLayout.SLIDE_END) return@setOnTabSelectListener
            isLeft = selectTabIndex == 0
            if (bean != null){
                initAllChartView(bean!!)
            }else {
                getSelectDayReport()
            }
        }
    }

    override fun onFragmentResume() {
        super.onFragmentResume()
//        decideToGetDayReport()
    }

    override fun onDestroyView() {
        OkGo.getInstance().cancelTag(this)
        super.onDestroyView()
    }

    //region 初始化所有图表
    private fun initAllChartView(bean: DayReportBean) {
        if (bean.data == null) return
        //区分当前是左边还是右边的用户数据
//        val data = if (MGlobal.instance.currLeftSide) {
        val data = if (isLeft) {
            bean.data?.left
        } else {
            bean.data?.right
        }
        currHasReportData = data?.score ?: -1 >= 0
        calcCardInfoData(data)
        initRadarData(data)
        initSleepIndex(data)
        initSleepChartInfo(data)
        initSnoringInfo(data)
        initHeartRateInfo(data)
        initBreathRateInfo(data)
        initBodyMoveInfo(data)

    }

    private fun initSleepInfo() {
        item_score.init(getString(R.string.title_day_score), "")
        item_heart_rate.init(getString(R.string.text_heart_rate),getString(R.string.tv_heart_rate_unit))
        item_breath_rate.init(getString(R.string.text_breath_rate),getString(R.string.tv_avg_unit))
        item_snore_count.init(getString(R.string.text_snore_count),getString(R.string.tv_body_unit_1))
        item_intercept_count.init(getString(R.string.text_intercept_snore_num_tip),getString(R.string.tv_body_unit_1))
        item_body_move.init(getString(R.string.text_small_body_movement),getString(R.string.tv_body_unit_1))
        item_body_revolve.init(getString(R.string.text_avg_body_cnt),getString(R.string.tv_body_unit_1))
//        item_move_eye_sleep.init("动眼睡眠","分钟")
//        item_deep_sleep.init("深睡","分钟")
    }

    /**
     * 重置所有View
     */
    private fun resetAllView() {
        if (!currHasReportData) return
        val rb = ReportBean()
        val drb = DayReportBean()
        drb.data = rb
        initAllChartView(drb)
    }
    //endregion

    //region 计算卡片数据
    private fun calcCardInfoData(bean: SideBean?) {
        setFormatText(item_score.getText(), bean?.score ?: -1,1)
    }
    //endregion

    //region 雷达图和指标相关
    private fun initRadarData(bean: SideBean?) {
        radar_day.setValues(
                (bean?.summary_chart?.deep ?: -1) * 0.01f,
                (bean?.summary_chart?.rem ?: -1) * 0.01f,
                (bean?.summary_chart?.snore_count ?: -1) * 0.01f,
                (bean?.summary_chart?.sleep_during_time ?: -1) * 0.01f,
                (bean?.summary_chart?.away_bed ?: -1) * 0.01f,
                (bean?.summary_chart?.asleep_time ?: -1) * 0.01f
        )
    }

    /**
     * 四个指标
     */
    private fun initSleepIndex(bean: SideBean?) {
        val subReport = bean?.sub_report?.get(0)
        calcSleepTime(subReport)
        val h = subReport?.sleep_time_hour ?: -1
        val m = subReport?.sleep_time_minute ?: -1
        setFormatText(tv_sleep_duration, h * 60 + m, 0)
        setFormatText(tv_go_bed, subReport?.go_to_bed_time ?: -1L, 3)
        setFormatText(tv_on_bed, subReport?.wake_up_time ?: -1L, 3)
    }

    /**
     * 计算入睡时长
     */
    private fun calcSleepTime(subReport: SubReportBean?) {
        if (subReport?.sleep_data.isNullOrEmpty()) {
            tv_sleep_time.text = "--"
        } else {
            val start = subReport?.sleep_data!![0].start
            var end = 0L
            for (data in subReport.sleep_data!!) {
                if (data.status in 1..3) {
                    end = data.end
                    break
                }
            }
            if (end == 0L) end = start //这种情况等同于没睡 给默认值 0
            setFormatText(tv_sleep_time, (end - start).toInt() / 60, 0)
        }
    }
    //endregion

    //region 深浅睡眠详细
    private fun initSleepChartInfo(bean: SideBean?) {
        val deep = bean?.sub_report?.get(0)?.deep
        val light = bean?.sub_report?.get(0)?.light
        val rem = bean?.sub_report?.get(0)?.rem
        val awake = bean?.sub_report?.get(0)?.awake
        val curr = bean?.sub_report?.get(0)?.sleep_data
        /*ssv_deep_sleep.setSleepTimeAndType(deep?.value ?: -1, SleepStandardView.DEEP_SLEEP)
        setFormatText(tv_deep_sleep_duration, deep?.value ?: -1, 0)
        tv_deep_sleep_percent.text = if (deep?.percentage ?: -1 > 0) "${deep?.percentage}%" else "0%"

        ssv_light_sleep.setSleepTimeAndType(light?.value ?: -1, SleepStandardView.LIGHT_SLEEP)
        setFormatText(tv_light_sleep_duration, light?.value ?: -1, 0)
        tv_light_sleep_percent.text = if (light?.percentage ?: -1 > 0) "${light?.percentage}%" else "0%"

        ssv_rem.setSleepTimeAndType(rem?.value ?: -1, SleepStandardView.REM)
        setFormatText(tv_rem_duration, rem?.value ?: -1, 0)
        tv_rem_percent.text = if (rem?.percentage ?: -1 > 0) "${rem?.percentage}%" else "0%"

        ssv_awake.setSleepTimeAndType(awake?.value ?: -1, SleepStandardView.AWAKE)
        setFormatText(tv_awake_duration, awake?.value ?: -1, 0)
        tv_awake_percent.text = if (awake?.percentage ?: -1 > 0) "${awake?.percentage}%" else "0%"

        if (curr.isNullOrEmpty()) dsc_day.showNoData() else dsc_day.setChartDataNew(curr)*/
        if (curr.isNullOrEmpty()) dsc_day.showNoData() else dsc_day.setChartDataNew(curr)
    }
    //endregion

    //region 打鼾
    private fun initSnoringInfo(bean: SideBean?) {
        val currSnore = bean?.sub_report?.get(0)?.snore_count
        //val currSnoreTime = bean?.sub_report?.get(0)?.snore?.get(0)?.time
        val currIntervene = bean?.sub_report?.get(0)?.snore
        val currBgData = bean?.sub_report?.get(0)?.sleep_data
        calcSnoreCount(currSnore)
        calcInterveneCount(currIntervene)
        /*if (currSnore == null && currIntervene == null) {
            sec_snore_rate.showNoData()
        } else {
            sec_snore_rate.setChartDataNew(currBgData, currSnore, currIntervene)
        }
        setFormatText(tv_snore_time, currSnoreTime ?: -1, 0)*/
    }

    /**
     * 计算打鼾次数
     */
    private fun calcSnoreCount(snore_count: List<TimeStampBean>?) {
        if (snore_count == null) {
            setFormatText(item_snore_count.getText(), -1, 1)
        } else {
            var count = 0
            for (data in snore_count) {
                count += data.value
            }
            setFormatText(item_snore_count.getText(), count, 1)
        }
    }

    /**
     * 计算干预次数
     */
    private fun calcInterveneCount(snore: List<TimeStampBean>?) {
        if (snore == null) {
            setFormatText(item_intercept_count.getText(), -1, 1)
        } else {
            setFormatText(item_intercept_count.getText(), snore.size, 1)
        }
    }
    //endregion

    //region 平均心率
    private fun initHeartRateInfo(bean: SideBean?) {
        val heart = bean?.sub_report?.get(0)?.heart_beat_avg ?: -1
        val curr = bean?.sub_report?.get(0)?.heart_beat
        val currBgData = bean?.sub_report?.get(0)?.sleep_data
        val highest: String
        val lowest: String
        setFormatText(item_heart_rate.getText(), heart, 1)
    }
    //endregion

    //region 平均呼吸频率
    private fun initBreathRateInfo(bean: SideBean?) {
        val breath = bean?.sub_report?.get(0)?.breath_avg ?: -1
        setFormatText(item_breath_rate.getText(), breath, 1)
    }
    //endregion

    //region 体动和翻身
    private fun initBodyMoveInfo(bean: SideBean?) {
        val move = bean?.body_move_times ?: -1
        val revolve = bean?.body_revolve_times ?: -1
        val currMove = bean?.sub_report?.get(0)?.body_move
        val currRevolve = bean?.sub_report?.get(0)?.body_revolve
        val currBgData = bean?.sub_report?.get(0)?.sleep_data
        setFormatText(item_body_move.getText(), move, 1)
        setFormatText(item_body_revolve.getText(), revolve, 1)
        /*setFormatText(tv_body_revolve, revolve, 1)
        if (currMove.isNullOrEmpty() && currRevolve.isNullOrEmpty()) {
            bmc_body_move.showNoData()
        } else {
            val newMove = ArrayList<TimeValueBean>()
            val newRevolve = ArrayList<TimeValueBean>()
            if (!currMove.isNullOrEmpty()) {
                for (data in currMove) {
                    val tvb = TimeValueBean()
                    tvb.value = data.value
                    tvb.time = MUtil.getHM(data.time)
                    newMove.add(tvb)
                }
            }
            if (!currRevolve.isNullOrEmpty()) {
                for (data in currRevolve) {
                    val tvb = TimeValueBean()
                    tvb.value = data.value
                    tvb.time = MUtil.getHM(data.time)
                    newRevolve.add(tvb)
                }
            }
            bmc_body_move.setChartDataNew(currBgData, newMove, newRevolve)
        }*/
    }
    //endregion

    //region 公共方法

    /**
     * 设置文本
     */
    private fun setFormatText(tv: TextView, obj: Any, type: Int) {
        var text = ""
        when (type) {
            0 -> {//int数据显示时长 大于60分钟显示xHy格式 小于60分钟显示x min格式
                val value = obj as Int

//                text = if (value < 0) "--" else if (value >= 60) "${value / 60}h${value % 60}" else "${value}min"
                text = if (value < 0) "--" else if (value >= 60) "${value / 60}${unitHour}${value % 60}${unitMin}" else "${value}${unitMin}"
            }
            1 -> {//int数据显示文本
                val value = obj as Int
                text = if (value < 0) "--" else "$value"
            }
            2 -> {//String数据显示文本
                val str = obj as String
                text = if (str.isEmpty()) "--" else str
            }
            3 -> {//Long数据显示时长 大于60分钟显示xHy格式 小于60分钟显示x min格式
                val value = obj as Long
                text = if (value < 0L) "--" else MUtil.getHM(value)
            }
        }
        tv.text = text
    }

    //endregion

    //region 接口数据

    /**
     * 根据设备MAC地址和是否需要更新Token,决定去获取报告
     */
    private fun decideToGetDayReport() {
        if (SpUtil[Const.DEVICE_WIFI_MAC, ""].isEmpty()) {
            showToast(getString(R.string.text_no_device_tip))
            hideLoadingDialog()
            resetAllView()
        } else {
            context.showLoadingDialog()
            if (SpUtil.isNeedGetToken()) {
//                refreshToken()
                context.refreshToken(object:BaseActivity.OnRefreshTokenSuccessListener{
                    override fun onRefreshTokenSuccess() {
                        getSelectDayReport()
                    }

                })
            } else {
                getSelectDayReport()
            }
        }
    }

    /**
     * 获取日报
     */
    private fun getSelectDayReport() {
        val url = Const.getDayReport() + SpUtil[Const.DEVICE_WIFI_MAC, ""]
        val queryMap = HashMap<String, String>()
        queryMap["day"] = currDay
        OkGo.get<DayReportBean>(url).tag(this).params(queryMap).execute(object : JsonCallback<DayReportBean>() {

            override fun onNormalSuccess(response: Response<DayReportBean>) {
                if (response.body().error.isEmpty()) {
                    bean = response.body()
                    bean?.let {
                        initAllChartView(it)
                    }
                } else {
                    showToast(getString(R.string.tip_get_data_fail))
                    KLog.e("getSelectDayReport失败 response: $response")
                    if ("token_expired" == response.body().error) {
                        KLog.e("Token 无效")
                    }
                }
            }

            override fun onError(response: Response<DayReportBean>?) {
                showToast(getString(R.string.tip_get_data_fail))
                KLog.e("response: $response")
            }

            override fun onFinish() {
                hideLoadingDialog()
            }
        })
    }

    /**
     * 刷新Token
     */
//    private fun refreshToken() {
//        val url = Const.getToken() + SpUtil[Const.DEVICE_WIFI_MAC, ""]
//        val queryMap = HashMap<String, String>()
//        queryMap["access_key"] = Const.ACCESS_KEY
//        queryMap["secret_key"] = Const.SECRET_KEY
//        OkGo.get<TokenBean>(url).tag(this).params(queryMap).execute(object : JsonCallback<TokenBean>() {
//
//            override fun onNormalSuccess(response: Response<TokenBean>) {
//                if (response.body().error.isEmpty()) {
//                    SpUtil.put(Const.TOKEN_LOCAL, response.body().data?.token ?: "")
//                    SpUtil.put(Const.TOKEN_EXIST_TIME, System.currentTimeMillis())
//                    getSelectDayReport()
//                } else {
//                    hideLoadingDialog()
//                    KLog.e("Token 更新失败 response: $response")
//                    when (response.body().error) {
//                        "key_error" -> KLog.e("公私钥错误")
//                        "mac_error" -> KLog.e("MAC地址格式错误")
//                    }
//                }
//            }
//
//            override fun onError(response: Response<TokenBean>?) {
//                hideLoadingDialog()
//                KLog.e("Token 更新失败 response: $response")
//            }
//        })
//    }
    //endregion

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    fun onReceiveEvent(event: ReportEvent) {
        if (event.type != Const.DAY_OPERATE) return
        if (event.paramMap.isNullOrEmpty()) return
        val year = event.paramMap["year"] as Int
        val month = event.paramMap["month"] as Int
        val day = event.paramMap["day"] as Int
        currDay = String.format(Locale.getDefault(), "%04d-%02d-%02d", year, month, day)
        decideToGetDayReport()
    }
}